package com.sync.platform.controller;

import com.sync.platform.common.Result;
import com.sync.platform.entity.DatabaseConfig;
import com.sync.platform.entity.SyncTask;
import com.sync.platform.service.DatabaseConfigService;
import com.sync.platform.service.SyncTaskService;
import com.sync.platform.service.TaskSchedulerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * Database synchronization controller
 */
@Controller
@RequestMapping("/sync/database")
public class DatabaseSyncController {

    private static final Logger logger = LoggerFactory.getLogger(DatabaseSyncController.class);

    @Autowired
    private DatabaseConfigService databaseConfigService;
    
    @Autowired
    private SyncTaskService syncTaskService;
    
    @Autowired
    private TaskSchedulerService taskSchedulerService;

    /**
     * Database sync list page
     */
    @GetMapping
    public String list(Model model) {
        model.addAttribute("databases", databaseConfigService.list());
        model.addAttribute("tasks", syncTaskService.getDatabaseSyncTasks());
        model.addAttribute("pageTitle", "同步平台 - 数据库同步");
        return "sync/database/list";
    }

    /**
     * Add database sync page
     */
    @GetMapping("/add")
    public String add(Model model) {
        model.addAttribute("databases", databaseConfigService.list());
        model.addAttribute("pageTitle", "同步平台 - 添加数据库同步");
        return "sync/database/edit";
    }

    /**
     * Edit database sync page
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable Long id, Model model) {
        SyncTask task = syncTaskService.getById(id);
        if (task == null) {
            return "redirect:/sync/database";
        }
        
        model.addAttribute("task", task);
        model.addAttribute("databases", databaseConfigService.list());
        model.addAttribute("pageTitle", "同步平台 - 编辑数据库同步");
        return "sync/database/edit";
    }
    
    /**
     * Save database sync task
     */
    @PostMapping("/save")
    @ResponseBody
    public Result<?> save(@RequestBody Map<String, Object> params) {
        try {
            logger.info("Saving database sync task: {}", params);
            
            // Create task entity
            SyncTask task = new SyncTask();
            
            // Set ID if provided (for update)
            if (params.containsKey("id") && params.get("id") != null) {
                String idStr = params.get("id").toString();
                if (!idStr.isEmpty()) {
                    task.setId(Long.parseLong(idStr));
                }
            }
            
            // Set task name and description
            task.setName(params.get("taskName").toString());
            if (params.containsKey("description")) {
                task.setLastExecutionMessage(params.get("description").toString());
            }
            
            // Set source and target database IDs
            task.setSourceId(Long.parseLong(params.get("sourceDatabase").toString()));
            task.setTargetId(Long.parseLong(params.get("targetDatabase").toString()));
            
            // Set cron expression if scheduled
            boolean enableSchedule = params.containsKey("enableSchedule") && 
                                    Boolean.parseBoolean(params.get("enableSchedule").toString());
            if (enableSchedule && params.containsKey("cronExpression")) {
                task.setCronExpression(params.get("cronExpression").toString());
            }
            
            // Get source tables (if selected)
            List<String> sourceTables = null;
            if (params.containsKey("sourceTables") && params.get("sourceTables") != null) {
                sourceTables = (List<String>) params.get("sourceTables");
            }
            
            // Get sync options
            boolean createTableIfNotExists = params.containsKey("createTableIfNotExists") && 
                                            Boolean.parseBoolean(params.get("createTableIfNotExists").toString());
            boolean truncateBeforeSync = params.containsKey("truncateBeforeSync") && 
                                        Boolean.parseBoolean(params.get("truncateBeforeSync").toString());
            
            // Get incremental sync options
            boolean incrementalSync = params.containsKey("incrementalSync") && 
                                     Boolean.parseBoolean(params.get("incrementalSync").toString());
            String incrementalColumn = null;
            if (incrementalSync && params.containsKey("incrementalColumn")) {
                incrementalColumn = params.get("incrementalColumn").toString();
            }
            
            // Save task
            boolean success = syncTaskService.saveDatabaseSyncTask(
                task, sourceTables, createTableIfNotExists, truncateBeforeSync, incrementalSync, incrementalColumn);
            
            return success ? Result.success() : Result.fail("保存失败");
        } catch (Exception e) {
            logger.error("Error saving database sync task: {}", e.getMessage(), e);
            return Result.fail("保存失败: " + e.getMessage());
        }
    }
    
    /**
     * Execute sync task
     */
    @PostMapping("/{id}/execute")
    @ResponseBody
    public Result<?> execute(@PathVariable Long id) {
        try {
            Map<String, Object> result = syncTaskService.executeTask(id);
            return (boolean) result.get("success") 
                ? Result.success(result) 
                : Result.fail((String) result.get("message"));
        } catch (Exception e) {
            logger.error("Error executing sync task: {}", e.getMessage(), e);
            return Result.fail("执行失败: " + e.getMessage());
        }
    }
    
    /**
     * Update task status
     */
    @PutMapping("/{id}/status")
    @ResponseBody
    public Result<?> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
        try {
            SyncTask task = syncTaskService.getById(id);
            if (task == null) {
                return Result.fail("任务不存在");
            }
            
            task.setStatus(status);
            boolean success = syncTaskService.updateById(task);
            
            if (success) {
                // Schedule or cancel based on new status
                if (status == 1 && task.getCronExpression() != null && !task.getCronExpression().isEmpty()) {
                    // Enable task - schedule it
                    boolean scheduled = taskSchedulerService.scheduleTask(id, task.getCronExpression());
                    logger.info("Task {} {} after status change to enabled", 
                               id, scheduled ? "scheduled" : "failed to schedule");
                } else {
                    // Disable task - cancel it
                    boolean cancelled = taskSchedulerService.cancelTask(id);
                    logger.info("Task {} {} after status change to disabled", 
                               id, cancelled ? "cancelled" : "was not scheduled");
                }
            }
            
            return success ? Result.success() : Result.fail("更新状态失败");
        } catch (Exception e) {
            logger.error("Error updating task status: {}", e.getMessage(), e);
            return Result.fail("更新状态失败: " + e.getMessage());
        }
    }
    
    /**
     * Update cron expression
     */
    @PutMapping("/{id}/cron")
    @ResponseBody
    public Result<?> updateCronExpression(@PathVariable Long id, @RequestParam String cronExpression) {
        try {
            logger.info("Updating cron expression for task {}: {}", id, cronExpression);
            
            SyncTask task = syncTaskService.getById(id);
            if (task == null) {
                return Result.fail("任务不存在");
            }
            
            task.setCronExpression(cronExpression);
            boolean success = syncTaskService.updateById(task);
            
            if (success) {
                // Schedule or cancel the task based on cron expression and status
                if (cronExpression != null && !cronExpression.isEmpty() && task.getStatus() == 1) {
                    // Schedule/reschedule the task
                    boolean scheduled = taskSchedulerService.rescheduleTask(id, cronExpression);
                    logger.info("Task {} {} with cron expression: {}", 
                               id, scheduled ? "scheduled" : "failed to schedule", cronExpression);
                } else {
                    // Cancel the task
                    boolean cancelled = taskSchedulerService.cancelTask(id);
                    logger.info("Task {} {}", id, cancelled ? "cancelled" : "was not scheduled");
                }
            }
            
            return success ? Result.success() : Result.fail("更新定时表达式失败");
        } catch (Exception e) {
            logger.error("Error updating cron expression: {}", e.getMessage(), e);
            return Result.fail("更新定时表达式失败: " + e.getMessage());
        }
    }

    /**
     * Delete sync task
     */
    @DeleteMapping("/{id}")
    @ResponseBody
    public Result<?> delete(@PathVariable Long id) {
        // Cancel any scheduled tasks first
        taskSchedulerService.cancelTask(id);
        
        boolean success = syncTaskService.removeById(id);
        return success ? Result.success() : Result.fail("删除失败");
    }
    
    /**
     * Get scheduled tasks info
     */
    @GetMapping("/scheduled")
    @ResponseBody
    public Result<?> getScheduledTasks() {
        try {
            List<String> scheduledTasks = taskSchedulerService.getScheduledTasks();
            return Result.success(scheduledTasks);
        } catch (Exception e) {
            logger.error("Error getting scheduled tasks: {}", e.getMessage(), e);
            return Result.fail("获取定时任务信息失败: " + e.getMessage());
        }
    }
} 